package com.rpctest.myrpc.server;

import com.rpctest.myrpc.common.RpcRequest;
import com.rpctest.myrpc.common.RpcResponse;
import com.rpctest.myrpc.common.User;
import com.rpctest.myrpc.serialize.Serializer;
import com.rpctest.myrpc.serialize.SerializerImpl.SerializerImpl;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.logging.Logger;

/**
 * @ClassName ServerHandler
 * @Description TODO
 * @Author 11
 * @Date 2021/3/31 15:45
 * @Version 1.0
 */
public class ServerHandler implements Runnable {

//    Logger logger = (Logger) LoggerFactory.getLogger(ServerHandler.class);
    private Socket socket;
//    private Class<? extends Serializer> serializer = (Class<? extends Serializer>) SerializerImpl.class;
    private Serializer serializerInstance;




    public ServerHandler(Socket socket) {
        this.socket=socket;
    }


    @Override
    public void run() {
        InputStream in = null;
        OutputStream out= null;

        try {
            byte[] recv = new byte[1024];
            in = socket.getInputStream();
            in.read(recv);
            String requestStr = new String(recv);
            System.out.println("服务器收到信息： "+ requestStr);
            //反序列化
            serializerInstance = SerializerImpl.class.getConstructor().newInstance();
            RpcRequest req = (RpcRequest) serializerInstance.deserialize(recv, RpcRequest.class);

            RpcResponse res  = process(req);  //开始远程调用
            User u = (User) res.getResult();
            System.out.println("远程调用后的对象   ："+u.getName());
            System.out.println("----------1--------------");
            byte[] returnRes = serializerInstance.serialize(res);
            System.out.println("----------2--------------");
            out = socket.getOutputStream();
            System.out.println("----------3--------------");
            out.write(returnRes);
            out.flush();
            System.out.println("-----------4-------------");
            RpcResponse test = (RpcResponse) serializerInstance.deserialize(returnRes, RpcResponse.class);
            System.out.println("发送的对象： "+test.toString());
            out.close();
        } catch (Exception e)  {
            e.printStackTrace();
        } finally {
            if (in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                socket=null;
            }
        }


    }

    private RpcResponse process(RpcRequest req) {
        //  make response
        RpcResponse res = new RpcResponse();
        res.setRequestId(req.getRequestId());
        // match service bean   后续实现服务注册
        //从spring容器中拿出实现类
        //通过requestid得到实现类类名
//        String implClassName= RPC.getServerConfig().getServerImplMap().get(request.getServiceId());
        String implClassName="User";
//        Object serviceBean = BioServer.applicationContext.getBean(req.getClassName());
        try{
            //通过类名得到Bean  实现类Bean
            System.out.println(BioServer.applicationContext.getBeanDefinitionNames().toString());
            Object implClassBean=BioServer.applicationContext.getBean(implClassName);
            //通过Bean得到实现类 class对象
            Class implClass=Class.forName(implClassBean.getClass().getName());
//            Class implClass=Class.forName(serviceBean.getClass().getName());
            //class对象获得方法
//            Method method=implClass.getDeclaredMethod(req.getMethodName(),req.getParameterTypes());
            String methodName = req.getMethodName();
            Class<?>[] parameterTypes = req.getParameterTypes();
            Object[] parameters = req.getParameters();
            if (parameters.length==0){
                //无参方法
                Method method=implClass.getDeclaredMethod(methodName);
//                Object implObj=RPC.serverContext.getBean(implClass);
                res.setResult(method.invoke(implClassBean));
                res.setErrorMsg("你好呀没有错误噢！");
            }else {
                int parameterNums=req.getParameters().length;
                parameterTypes=new Class[parameterNums];
                for (int i = 0; i <parameterNums ; i++) {
                    parameterTypes[i]=parameters[i].getClass();
                }
                Method method=implClass.getDeclaredMethod(req.getMethodName(),parameterTypes);
//                Object implObj=RPC.serverContext.getBean(implClass);
                res.setResult(method.invoke(implClassBean,parameters));
                res.setErrorMsg("你好呀没有错误噢！");
            }




//
//            //通过反射拿到接口的class对象
//            Class.forName(req.getClassName());
//            //从spring容器中拿出实现类
//            //获取实现类的class对象
//            //获取请求方法的Method对象
//            //通过反射执行其方法
//            //组织返回对象
        } catch (Exception e) {
            e.printStackTrace();
        }

        return res;
    }
}
